package cn.yj.frame.config;

import cn.yj.frame.annotation.RpcReference;
import cn.yj.frame.proxy.RpcReferenceProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.lang.reflect.Field;

/**
 * 处理注解@RpcReference依赖注入
 *
 * @author 永健
 * @since 2022-01-18 16:56
 */
public class RpcReferenceAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

    /**
     * 不要挑刺哦～
     *
     * 只是处理注入，不考虑循环依赖问题，不考虑递归实例化问题
     *
     * 只是针对这个远程调用的实现实践
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

        Class<?> aClass = bean.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            RpcReference annotation = field.getAnnotation(RpcReference.class);
            if (annotation == null) {
                continue;
            }
            String fieldBeanName = annotation.name();
            if ("".equals(fieldBeanName)) {
                fieldBeanName = field.getName();
            }
            field.setAccessible(true);
            try {
                // 调用方不需要实现类，通过代理的方式注入代理对象，在invoke的时候通过netty调用服务方接口
                field.set(bean, RpcReferenceProxyFactory.createProxy(field.getType(), fieldBeanName));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return super.postProcessAfterInstantiation(bean, beanName);
    }
}
